﻿using System.Collections;
using System.Diagnostics;

namespace DimensionsHelper.LanguageService.Syntax;

public class SelectStatement : Statement, IReadOnlyList<SelectCaseClause>
{
    private readonly SyntaxToken _caseKeywordToken;
    private readonly SyntaxList<SelectCaseClause> _clauses;


    private readonly SyntaxToken _selectKeywordToken;
    private Expression _expression;

    internal SelectStatement(SyntaxToken selectKeywordToken, SyntaxToken caseKeywordToken, SyntaxNode? parent) :
        base(SyntaxKinds.SelectStatement, parent)
    {
        SetChildField(ref _selectKeywordToken, selectKeywordToken);
        SetChildField(ref _caseKeywordToken, caseKeywordToken);
        _clauses = new SyntaxList<SelectCaseClause>();
        _expression = EmptyExpression.Default;
    }


    public SyntaxToken SelectKeywordToken => _selectKeywordToken;

    public SyntaxToken CaseKeywordToken => _caseKeywordToken;

    public Expression Expression => _expression;


    public int Count => _clauses.Count;

    public SelectCaseClause this[int index] => _clauses[index];

    public IEnumerator<SelectCaseClause> GetEnumerator()
    {
        return _clauses.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }


    public SelectStatement Update(Expression expression)
    {
        SetChildField(ref _expression, Expression.IsEmptyExpression, expression);
        return this;
    }


    public void AddClause(SelectCaseClause clause)
    {
        AddChildMemberToReadOnlyField(_clauses, clause);
    }


    public override void AcceptVisitor<T>(SyntaxNodeVisitor<T> visitor)
    {
        Accept(visitor, SelectKeywordToken, CaseKeywordToken, Expression);
        AcceptList(visitor, _clauses);
    }
}


public static partial class NodeFactory
{
    public static SelectStatement CreateSelectStatement(SyntaxNode? parent, SyntaxToken selectKeywordToken,
        SyntaxToken caseKeywordToken)
    {
        Debug.Assert(selectKeywordToken.IsNode(SyntaxKinds.SelectKeywordToken));
        return new SelectStatement(selectKeywordToken, caseKeywordToken, parent);
    }
}